#include "cacheapi.h"
#include "client_impl.h"
#include "../inc/logger.h"
#include <mutex>
//#include "../cache/cache.h"
/*
namespace  MemCache{

Cache* cache=NULL;

int  Initialize(const char* configPath)
{
	if(!cache)
		cache=new Cache();
	return cache->Initialize( configPath);
}
int  Initialize(string addr,unsigned short port)
{
	if(!cache)
		cache=new Cache();
	return cache->Initialize( addr, port);
}
int  Release()
{
	if(!cache)
		return -1;
	return cache->Release();
}
bool IsConnected()
{
	if(!cache)
		return false;
	return cache->IsConnected();
}
int ClearDB()
{
	if(!cache)
		return -1;
	return cache->ClearDB();
}
int Select(unsigned char db,string* errstr)
{
	if(!cache)
		return -1;
	return cache->Select(db,errstr);
}
int Set(string key,string value,string* errstr)
{
	if(!cache)
		return -1;
	return cache->Set(key,value,errstr);
}
int Get(string key,string& value,string* errstr)
{
	if(!cache)
		return -1;
	return cache->Get(key,value,errstr);
}
int Del(std::string key,std::string* errstr)
{
	if(!cache)
		return -1;
	return cache->Del(key,errstr);
}
int SaveData(const Storage::SaveDataRequest& request,Storage::SaveDataResponse& resp,string* errstr)
{
	if(!cache)
		return -1;
	return cache->SaveData(request,resp,errstr);
}
int QueryData(const Storage::QueryDataRequest& request,Storage::QueryDataResponse& resp,std::string* errstr)
{
	if(!cache)
		return -1;
	return cache->QueryData(request,resp,errstr);
}

void Set(unsigned char dataset,const string& key,const string& value,void* userdata, std::function<void(const CallbackArg&)> cb)
{
	if(!cache)
		throw "not initialize cache";
	return cache->Set(dataset, key,value, userdata, cb);
}
void Get(unsigned char dataset,const string& key,void* userdata, std::function<void(const CallbackArg&)> cb)
{
	if(!cache)
		throw "not initialize cache";
	return cache->Get(dataset, key,userdata, cb);
}

};
*/
namespace  LocalCache{

std::mutex mtx;
std::unordered_map<string,string> mapKeyValue;//<key,value>
bool inited=false;
int  Initialize()
{
	if(!inited)
	{
		inited=true;
	    mapKeyValue.rehash(1000000);
	}
	return 0;
}

int  Release()
{
	inited=false;
	return 0;
}
int Set(string key,string value,string* errstr)
{
	if(!inited)
		return -1;
	int total=0;
	std::unique_lock<mutex> lock(mtx);
	mapKeyValue[key]=value;
	total=mapKeyValue.size();
	LOG4_DEBUG("Set memcache[%d,%d],key=%s,value:%s",&mapKeyValue,total,key.c_str(),value.c_str());
	return 0;
}
int Get(string key,string& value,string* errstr)
{
	if(!inited)
		return -1;
	int find=-1;
	int total=0;
	std::unique_lock<mutex> lock(mtx);
	std::unordered_map<string,string>::iterator it=mapKeyValue.find(key);
	if(it!=mapKeyValue.end()){
		value=mapKeyValue[key];
		find=0;
	}
	total=mapKeyValue.size();
	if(find==0){
	    LOG4_DEBUG("Find memcache[%d,%d],key=%s,value:%s",&mapKeyValue,total,key.c_str(),value.c_str());
	}
	else{
		LOG4_DEBUG("Not find memcache[%d,%d],key=%s",&mapKeyValue,total,key.c_str());
	}
	return find;
}
int Del(std::string key,std::string* errstr)
{
	if(!inited)
		return -1;
	int find=-1;
	int total=0;
	std::unique_lock<mutex> lock(mtx);
	std::unordered_map<string,string>::iterator it=mapKeyValue.find(key);
	if(it!=mapKeyValue.end()){
		mapKeyValue.erase(it);
		find=0;
	}
	total=mapKeyValue.size();
	if(find==0){
	    LOG4_DEBUG("Delete memcache[%d,%d],key=%s",&mapKeyValue,total,key.c_str());
	}
	else{
		LOG4_DEBUG("Delete memcache[%d,%d] but not find,key=%s",&mapKeyValue,total,key.c_str());
	}
	return find;
}
};